package junior.db.dao.update;

import junior.db.dao.base.FilterMapperProvider;
import junior.db.dao.base.MybatisHelper;
import junior.db.dao.base.IEntityWrapper;
import junior.db.dao.base.INamespaceAware;

import java.util.List;
import java.util.Map;

/**
 * @author wubo
 * @date 2024/9/3 10:07
 */
public class UpdateMapperProvider extends FilterMapperProvider {
    
    public String insert(Map<String, Object> param) {
        Object entity = param.get("entity");
        InsertOption option = (InsertOption) param.get("option");
        return UpdateSqlHelper.insert(entity, option, (path, val) -> val == null ? "null" : "#{" + path + ",javaType=" + val.getClass().getTypeName() + "}");
    }
    
    public String batchInsert(Map<String, Object> param) {
        List entities = (List) param.get("entities");
        BatchInsertOption option = (BatchInsertOption) param.get("option");
        return UpdateSqlHelper.batchInsert(entities, option, (path, val) -> val == null ? "null" : "#{" + path + ",javaType=" + val.getClass().getTypeName() + "}");
    }
    
    public String upsert(Map<String, Object> param) {
        Object entity = param.get("entity");
        UpsertOption option = (UpsertOption) param.get("option");
        return UpdateSqlHelper.upsert(entity, option, (path, val) -> val == null ? "null" : "#{" + path + ",javaType=" + val.getClass().getTypeName() + "}");
    }
    
    public String batchUpsert(Map<String, Object> param) {
        List entities = (List) param.get("entities");
        BatchUpsertOption option = (BatchUpsertOption) param.get("option");
        return UpdateSqlHelper.batchUpsert(entities, option, (path, val) -> val == null ? "null" : "#{" + path + ",javaType=" + val.getClass().getTypeName() + "}");
    }
    
    public String update(Map<String, Object> param) {
        Object entity = param.get("entity");
        UpdateOption option = (UpdateOption) param.get("option");
        return UpdateSqlHelper.update(entity, option, (path, val) -> val == null ? "null" : "#{" + path + ",javaType=" + val.getClass().getTypeName() + "}");
    }
    
    public String batchUpdate(Map<String, Object> param) {
        List entities = (List) param.get("entities");
        BatchUpdateOption option = (BatchUpdateOption) param.get("option");
        return UpdateSqlHelper.batchUpdate(entities, option, (path, val) -> val == null ? "null" : "#{" + path + ",javaType=" + val.getClass().getTypeName() + "}");
    }
    
    public String updateField(UpdateFieldOption option) {
        return doUpdateField(option, "");
    }
    
    public String updateFieldWithEntityClass(Map<String, Object> param) {
        UpdateFieldOption option = (UpdateFieldOption) param.get("option");
        Class<?> entityClass = (Class<?>) param.get("entityClass");
        option.setEntityClass(entityClass);
        return doUpdateField(option, "option");
    }
    
    private String doUpdateField(UpdateFieldOption option, String path) {
        return UpdateSqlHelper.updateField(option, path, (valuePath, val) -> val == null ? "null" : "#{" + valuePath + ",javaType=" + val.getClass().getTypeName() + "}");
    }
    
    public String delete(DeleteOption option) {
        return doDelete(option, "");
    }
    
    public String deleteWithEntityClass(Map<String, Object> param) {
        DeleteOption option = (DeleteOption) param.get("option");
        Class<?> entityClass = (Class<?>) param.get("entityClass");
        option.setEntityClass(entityClass);
        return doDelete(option, "option");
    }
    
    private String doDelete(DeleteOption option, String path) {
        return UpdateSqlHelper.delete(option, path, (valuePath, val) -> val == null ? "null" : "#{" + valuePath + ",javaType=" + val.getClass().getTypeName() + "}");
    }
    
    public static String getColumn(INamespaceAware option, IEntityWrapper entityWrapper, String field) {
        return MybatisHelper.field2Column(option.getNamespace(), entityWrapper.getEntityClass(), field);
    }
    
    public static void setEntity(SingleInsertOption option, Object entity) {
        option.init(entity.getClass(), entity);
    }
    
    public static void setEntity(AbstractBatchInsertOption option, Object[] entities) {
        option.init(entities[0].getClass(), entities);
    }
    
    public static void setEntity(UpdateOption option, Object entity) {
        option.init(entity.getClass(), entity);
    }
    
    public static void setEntity(BatchUpdateOption option, Object[] entities) {
        option.init(entities[0].getClass(), entities);
    }
}
